package com.luxf.base.domainevent.annotation;

import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.util.ReflectionUtils;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

public class AggregateRootIdChecker implements ApplicationRunner {

    @Resource
    private EntityManager entityManager;

    @Override
    public void run(ApplicationArguments args) {
        // TODO: 可以使用类扫描框架, 进行扫描需要check的类.
        MetamodelImplementor metaModelImplementor = (MetamodelImplementor) entityManager.getMetamodel();
        Map<String, EntityPersister> entityPersistableMap = metaModelImplementor.entityPersisters();
        entityPersistableMap.values().forEach(this::checkAggregateRootId);
    }

    private void checkAggregateRootId(EntityPersister persistable) {
        Class<?> targetClass = persistable.getMappedClass();
        if (!targetClass.isAnnotationPresent(AggregateRoot.class)) {
            return;
        }
        AtomicInteger count = new AtomicInteger(0);
        ReflectionUtils.doWithFields(targetClass, field -> count.getAndIncrement(),
                field -> field.isAnnotationPresent(AggregateRootId.class));
        if (count.get() != 1) {
            throw new RuntimeException("聚合根没有主键或者存在多个主键!");
        }
    }
}
